package com.nulldev.util.web.YouTubeExtractor.subtitles;

import java.util.List;
import java.util.concurrent.TimeUnit;

import com.nulldev.util.VariableAPI.StringsUtil;
import com.nulldev.util.VariableAPI.MathUtil.TimeUtil;
import com.nulldev.util.VariableAPI.util.strings.splitters.Splitters;
import com.nulldev.util.concurrency.threadIt.v4.emapi.ExecutorManager;
import com.nulldev.util.concurrency.threadIt.v4.emapi.uft.Executable;
import com.nulldev.util.io.IOUtils;
import com.nulldev.util.logging.Logger;
import com.nulldev.util.logging.LoggerFactory;

public class SRTBuilder {

	public static final String VERSION = "1.0.0";
	private static final Logger log = LoggerFactory.getLogger();
	private int index = 1;

	private final StringBuilder builder;

	public SRTBuilder() {
		this.builder = new StringBuilder(IOUtils.STRING_ALLOC_BUFFER);
	}

	public void add(final Subtitle subtitle) {
		if (subtitle == null)
			return;
		final String text = subtitle.text();
		final float from = subtitle.start();
		final float to = subtitle.end();
		final boolean treatAsMills = subtitle.treatAsMilliseconds();
		if (text == null) {
			log.error("add(): Blank entry was skipped! [text=" + text + ",from=" + from + ",to=" + to + "]");
			return;
		}
		this.builder.append(this.index + "\n");
		final String c0 = treatAsMills ? convertNative(from) : convert(from);
		final String c1 = treatAsMills ? convertNative(to) : convert(to);
		this.builder.append(c0 + " --> " + c1);
		final String[] lines = Splitters.splitString(text, "\n");
		for (final String line : lines) {
			this.builder.append(StringsUtil.unescapeHtml3(line) + "\n");
		}
		this.builder.append("\n");
		this.index += 1;
	}

	public void addAll(final List<Subtitle> subtitles) {
		if (subtitles == null || subtitles.isEmpty())
			return;
		final Executable<?> f = ExecutorManager.make(() -> {
			for (final Subtitle subtitle : subtitles) {
				this.add(subtitle);
			}
			return null;
		});
		WebVTTBuilder.APPEND_ACCELERATOR.asyncSubmit(f).waitFor(60, TimeUnit.SECONDS);
	}

	public String build() {
		return this.builder.toString();
	}

	private String convert(final float seconds) {
		return TimeUtil.milliToStringSRT((long) (seconds * 1000));
	}

	private String convertNative(final float seconds) {
		return TimeUtil.milliToStringSRT((long) seconds);
	}
}
